﻿using SqlSugar;
using System.Data;
using System.Linq.Expressions;
using TianYu.Core.Common;

namespace TianYu.Core.DataBase.Repository
{
    public interface IBaseRepository<TEntity> where TEntity : BaseModel
    {
        /// <summary>
        /// SqlsugarClient实体
        /// </summary>
        SqlSugarScope Db { get; }

        #region 增

        void AddQueue(string sql, List<SugarParameter> parsmeters);
        void AddQueue(string sql, SugarParameter parsmeter);

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        Task<int> AddAsync(TEntity model);

        /// <summary>写入实体数据</summary>
        /// <param name="entity">实体类</param>
        /// <param name="insertColumns">指定只插入列</param>
        /// <returns>返回自增量列</returns>
        Task<int> AddAsync(TEntity entity, Expression<Func<TEntity, object>> insertColumns = null);

        /// <summary>批量添加</summary>
        /// <param name="listEntity"></param>
        /// <returns></returns>
        Task<int> AddAsync(List<TEntity> listEntity);

        /// <summary>写入实体数据</summary>
        /// <param name="entity">实体类</param>
        /// <returns></returns>
        void AddQueue(TEntity entity);

        /// <summary>写入实体数据</summary>
        /// <param name="entity">实体类</param>
        /// <param name="insertColumns">指定只插入列</param>
        /// <returns>返回自增量列</returns>
        void AddQueue(TEntity entity, Expression<Func<TEntity, object>> insertColumns = null);

        /// <summary>批量插入实体(速度快)</summary>
        /// <param name="listEntity">实体集合</param>
        /// <returns>影响行数</returns>
        void AddQueue(List<TEntity> listEntity);

        #endregion


        #region 删

        /// <summary>
        /// 根据id 删除某一实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<bool> DeleteByIdAsync(object id);

        /// <summary>
        /// 根据对象，删除某一实体
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        Task<bool> DeleteAsync(TEntity model);

        /// <summary>
        /// 根据id数组，删除实体list
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        Task<bool> DeleteByIdsAsync(params object[] ids);

        /// <summary>删除指定ID集合的数据</summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>根据实体删除一条数据</summary>
        /// <param name="entity">实体类</param>
        /// <returns></returns>
        void DeleteQueue(TEntity entity);

        /// <summary>删除指定ID的数据</summary>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        void DeleteQueue(object id);

        /// <summary>删除指定ID集合的数据(批量删除)</summary>
        /// <param name="ids">主键ID集合</param>
        /// <returns></returns>
        void DeleteQueue(params object[] ids);

        /// <summary>删除指定ID集合的数据（指令进行缓存不立即执行，调用<c>SaveQueuesAsync(bool)</c>批量提交）</summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        void DeleteQueue(Expression<Func<TEntity, bool>> whereExpression);

        #endregion


        #region 改

        /// <summary>更新model</summary>
        /// <param name="model"></param>
        /// <returns></returns>
        Task<bool> UpdateAsync(TEntity model);

        /// <summary>
        /// 根据model，更新，带where条件
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="strWhere"></param>
        /// <returns></returns>
        Task<bool> UpdateAsync(TEntity entity, string strWhere);

        Task<bool> UpdateAsync(string strSql, params SugarParameter[] parameters);

        Task<bool> UpdateAsync(object operateAnonymousObjects);

        /// <summary>
        /// 根据model，更新指定列
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="lstColumns"></param>
        /// <param name="lstIgnoreColumns"></param>
        /// <param name="strWhere"></param>
        /// <returns></returns>
        Task<bool> UpdateAsync(TEntity entity, List<string> lstColumns = null, List<string> lstIgnoreColumns = null, string strWhere = "");

        Task<bool> UpdateAsync(TEntity entity, Expression<Func<TEntity, object>> columnsExpression = null,
            Expression<Func<TEntity, object>> ignoreColumnsExpression = null, Expression<Func<TEntity, bool>> whereExpression = null);

        Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>只更新值变更的属性</summary>
        /// <param name="entity"></param>
        /// <param name="whereExpression">更新条件，为空则按主键字段更新</param>
        /// <param name="ignoreColumnsExpression">忽略更新字段</param>
        /// <returns></returns>
        Task<bool> UpdateWithChangedAsync(TEntity entity, Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, object>> ignoreColumnsExpression = null);




        /// <summary>更新实体数据(主键为条件)</summary>
        /// <param name="entity">博文实体类</param>
        /// <returns></returns>
        void UpdateQueue(TEntity entity);

        void UpdateQueue(TEntity entity, string strWhere);

        void UpdateQueue(object operateAnonymousObjects);

        void UpdateQueue(TEntity entity, List<string> lstColumns = null, List<string> lstIgnoreColumns = null, string strWhere = "");

        void UpdateQueue(TEntity entity, Expression<Func<TEntity, object>> columnsExpression = null, Expression<Func<TEntity, object>> ignoreColumnsExpression = null, Expression<Func<TEntity, bool>> whereExpression = null);

        void UpdateQueue(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression);
         
        /// <summary>只更新值变更的属性</summary>
        /// <param name="entity"></param>
        /// <param name="whereExpression">更新条件，为空则按主键字段更新</param>
        /// <param name="ignoreColumnsExpression">忽略更新字段</param>
        /// <returns></returns>
        void UpdateWithChangedQueue(TEntity entity, Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, object>> ignoreColumnsExpression = null);

        #endregion


        #region 查
        Task<bool> AnyAsync(Expression<Func<TEntity, bool>> expression);

        Task<TResult> MaxAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression);

        Task<TResult> MaxAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);

        Task<TResult> SumAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression);

        Task<TResult> SumAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 根据Id查询实体
        /// </summary>
        /// <param name="objId"></param>
        /// <returns></returns>
        Task<TEntity> GetAsync(object objId);
        Task<TEntity> GetAsync(object objId, bool blnUseCache = false);
        Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> whereExpression);
        Task<TEntity> GetAsync(Expression<Func<TEntity, TEntity>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 根据id数组查询实体list
        /// </summary>
        /// <param name="lstIds"></param>
        /// <returns></returns>
        Task<List<TEntity>> GetListAsync(params object[] lstIds);

        /// <summary>根据条件查询一条数据(多条根据排序取第一条记录)</summary> 
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="orderByExpression">排序表达式</param>
        /// <returns>数据实体</returns>
        Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);

        /// <summary>根据条件查询一条数据(多条根据排序取第一条记录)</summary> 
        /// <param name="whereExpression">条件表达式</param>
        Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>查询单个字段值</summary>  
        Task<TResult> GetFieldValueAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>查询单个字段值</summary>  
        Task<List<TResult>> QueryFieldValueAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);




        /// <summary>
        /// 查询数据条数
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync();

        /// <summary>
        /// 带sql where查询
        /// </summary>
        /// <param name="strWhere"></param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(string strWhere);

        /// <summary>
        /// 根据表达式查询
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 根据表达式，指定返回对象模型，查询
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<List<TResult>> QueryAsync<TResult>(Expression<Func<TEntity, TResult>> expression);

        /// <summary>
        /// 根据表达式，指定返回对象模型，排序，查询
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression"></param>
        /// <param name="whereExpression"></param>
        /// <param name="strOrderByFileds"></param>
        /// <returns></returns>
        Task<List<TResult>> QueryAsync<TResult>(Expression<Func<TEntity, TResult>> expression, Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds);
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds);
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true, int intTop = 10);
        Task<List<TEntity>> QueryAsync(string strWhere, string strOrderByFileds);

        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, int intTop, string strOrderByFileds);
        Task<List<TEntity>> QueryAsync(string strWhere, int intTop, string strOrderByFileds);
        Task<List<T>> QuerySqlAsync<T>(string strSql, params SugarParameter[] parameters) where T : new();
        Task<DataTable> QueryTableAsync(string strSql, params SugarParameter[] parameters);
        Task<Dictionary<object, TEntity>> QueryDictionaryAsync(params object[] lstIds);

        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds);
        Task<List<TEntity>> QueryAsync(string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds);

        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, TEntity>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);

        Task<List<TResult>> QueryAsync<TResult>(Expression<Func<TEntity, TResult>> columns, Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 根据表达式，排序字段，分页查询
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="intPageIndex"></param>
        /// <param name="intPageSize"></param>
        /// <param name="strOrderByFileds"></param>
        /// <returns></returns>
        Task<PageModel<TEntity>> QueryPageAsync(Expression<Func<TEntity, bool>> whereExpression, int intPageIndex = 1, int intPageSize = 20, string strOrderByFileds = null);

        /// <summary>
        /// 根据表达式，排序字段，分页查询
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="orderByExpression">排序表达式</param>
        /// <param name="isAsc">是否升序</param>
        /// <param name="intPageIndex"></param>
        /// <param name="intPageSize"></param>
        /// <returns></returns>
        Task<PageModel<TEntity>> QueryPageAsync(Expression<Func<TEntity, bool>> whereExpression, int intPageIndex = 1, int intPageSize = 20, Expression<Func<TEntity, object>> orderByExpression = null, bool isAsc = true);

        #endregion



        /// <summary>
        /// 提交
        /// </summary>
        /// <param name="isTran"></param>
        /// <returns></returns>
        Task<int> SaveQueuesAsync(bool isTran = true);
    }
}
